from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.status import HTTP_404_NOT_FOUND, HTTP_204_NO_CONTENT
from rest_framework.viewsets import ModelViewSet

from .models import Student, Classes
from .serializers import StudentSerializer, ClassesSerializer

# Create your views here.
"""
视图集：
    django rest framework允许你将一组相关视图的逻辑组合在单个类(称为ViewSet)中，在其他框架中，
    你也可以找到概念上类似于Resources或者Controllers的类似视图

    Rest framework 传入视图的request对象不再是django默认的HttpRequest对象，而是 Rest framework提供的
    扩展了HttpRequest类的Request类的对象。其中提供了Parser解析器，在接收到请求后会自动根据Content-Type指名的请求数据类型(如json
    表单等)将请求数据进行parse解析为类字典对象保存到request对象中，所以无论前段发送的哪种格式的数据，我们都可以统一的方式读取数据

    如何完成逻辑删除：
        1、重写模型类的delete方法
        2、将查询改为条件查询
        
    限流：
        限流就是限制对接口的访问频次，不让别人频繁的获取你的数据，减轻服务器的压力
        限流的配置：在setting中配置
        
    自动生成官方接口文档(coreapi)：
        pip install coreapi -i https://pypi.douban.com/simple       安装依赖
        在setting中配置
        在项目总路由文件中配置路由
        

"""

"""
class StudentViewSet(viewsets.ViewSet):
    # 查询获取数据函数
    def list(self, request):                                 # rest framework框架规定了list为GET请求
        students = Student.objects.all()                     # 获取所有的学生信息，返回的是模型类集合
        serializer = StudentSerializer(students, many=True)  # 实例化序列化器，传入要转换的模型集合，多条数据则需加入many=True
        return Response(serializer.data)                     # 返回响应，返回序列化后的数据

    # 增加数据函数
    def create(self, request):                               # rest framework框架规定了create为POST请求
        # 获取前端传入的数据并通过序列化器传入数据进行反序列化，得到模型数据
        serializer = StudentSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)            # rest framework自带的校验工具，如果校验不通过则返回异常
        serializer.save()                                    # 保存数据
        return Response(serializer.data)                     # 返回响应，返回序列化后的数据

    # 查询单个数据
    def retrieve(self, request, pk):                        # rest framework框架规定了retrieve为GET请求
        try:
            student = Student.objects.get(id=pk)            # 如果查询到的id不一致
        except Student.DoesNotExist:                        # rest framework自带的抛出异常
            return Response(status=HTTP_404_NOT_FOUND)      # 改变状态码

        serializer = StudentSerializer(instance=student)    # 否则通过序列化器进行序列化，instance代表序列化，data代表反序列化
        return Response(serializer.data)                    # 返回序列化后的数据

    # 修改数据
    def update(self, request, pk):                          # rest framework框架规定了update为PUT请求
        try:                                                # 查询要修改的数据
            student = Student.objects.get(id=pk)            # 异常处理
        except Student.DoesNotExist:                        # rest framework自带的抛出异常
            return Response(status=HTTP_404_NOT_FOUND)      # 改变状态码
        # 序列化和反序列化时，没有传入instance= 时，save()方法执行的是create方法，传入时才会执行update方法
        serializer = StudentSerializer(instance=student, data=request.data)   # 获取前端传入的数据进行反序列化
        serializer.is_valid(raise_exception=True)            # rest framework自带的校验工具，如果校验不通过则返回异常
        serializer.save()                                    # 校验通过后修改数据
        return Response(serializer.data)                    # 通过序列化器的data属性获取序列化后的数据(json)返回前端

    # 删除数据
    def destroy(self, request, pk):
        try:                                                # 查询要删除的数据
            student = Student.objects.get(id=pk)            # 异常处理
        except Student.DoesNotExist:                        # rest framework自带的抛出异常
            return Response(status=HTTP_404_NOT_FOUND)      # 改变状态码

        student.delete()                                    # 没有异常则进行删除操作
        return Response(status=HTTP_204_NO_CONTENT)         # 并返回状态码
"""


# 学生信息视图集
class StudentViewSet(ModelViewSet):         # 继承ModelViewSet就能实现增删改查等功能
    """
    list:
        官方文档描述。 返回学生列表数据
    """
    # queryset = Student.objects.all()        # 只需定义好需要对应的查询集
    queryset = Student.objects.filter(is_delete=False, classes__is_delete=False)  # 也可以将查询改为条件查询可以避免逻辑删除后还能查询到已删除的数据
    serializer_class = StudentSerializer    # 和序列化器


# 班级信息视图集
class ClassesViewSet(ModelViewSet):         # 继承ModelViewSet就能实现增删改查等功能
    # queryset = Student.objects.all()        # 只需定义好需要对应的查询集
    queryset = Classes.objects.filter(is_delete=False)        # 将查询改为条件查询可以避免逻辑删除后还能查询到已删除的数据
    serializer_class = ClassesSerializer    # 和序列化器

    # 查询最新的数据
    # rest_framework提供的装饰器能我们进行路由的映射。methods为定义这个路由的请求方式
    @action(methods=['get'], detail=False)
    def last(self, request):
        classes = Classes.objects.filter(is_delete=False).last()                # 获取班级模型最后创建的信息
        serializer = self.get_serializer(classes)       # get_serializer拿到指定的序列化器并将要序列化的数据传入
        return Response(serializer.data)







